/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package simhya.matheval;

import org.sbml.jsbml.ASTNode;
import simhya.matheval.function.FunctionDefinition;

/**
 *
 * @author Luca
 */
public abstract class FunctionNode extends ExpressionNode {
    protected FunctionDefinition function;
    
    
    public FunctionNode(FunctionDefinition function, int numberOfChildren) {
        super(numberOfChildren);
        this.function = function;
        random = function.isRandomFunction();
    }

    String getExpressionString(boolean fullNumberRepresentation) {
        String s = "";
        s += function.getName() + "(";
        for (int i=0;i<super.numberOfChildren;i++)
            s += (i>0 ? "," : "") + children[i].getExpressionString(false);
        s += ")";
        return s;
    }


    abstract void computeValue();
    abstract void computeValue(SymbolArray varReference);
    abstract void computeValue(int evaluationCode);
    abstract void computeValue(SymbolArray varReference, int evaluationCode);
    abstract void computeValueLocal(SymbolArray localVariables);
    abstract void computeValueLocal(SymbolArray localVariables, SymbolArray globalVariables);
    abstract void computeValueLocal(SymbolArray localVariables, int evaluationCode);
    abstract void computeValueLocal(SymbolArray localVariables, SymbolArray globalVariables, int evaluationCode);
    
    
    void computeContinuousChangeStatus() {
        this.canChangeContinuously = false;
        for (ExpressionNode n : this.children) {
            n.computeContinuousChangeStatus();
            this.canChangeContinuously = this.canChangeContinuously || n.canChangeContinuously;
        }
    }
    void computeContinuousChangeStatus(SymbolArray varReference) {
        this.canChangeContinuously = false;
        for (ExpressionNode n : this.children) {
            n.computeContinuousChangeStatus(varReference);
            this.canChangeContinuously = this.canChangeContinuously || n.canChangeContinuously;
        }
    }
    void computeContinuousChangeStatusLocal(SymbolArray localVariables) {
        this.canChangeContinuously = false;
        for (ExpressionNode n : this.children) {
            n.computeContinuousChangeStatusLocal(localVariables);
            this.canChangeContinuously = this.canChangeContinuously || n.canChangeContinuously;
        }
    }
    void computeContinuousChangeStatusLocal(SymbolArray localVariables, SymbolArray globalVariables) {
        this.canChangeContinuously = false;
        for (ExpressionNode n : this.children) {
            n.computeContinuousChangeStatusLocal(localVariables,globalVariables);
            this.canChangeContinuously = this.canChangeContinuously || n.canChangeContinuously;
        }
    }
    
    

    @Override
    ASTNode convertToJSBML() {
        throw new UnsupportedOperationException("Not supported yet.");
    }
    
    @Override
    String toJavaCode() {
        String s;
        s = function.toJavaCode() + "(";
        for (int i=0;i<this.numberOfChildren;i++)
            s+= (i > 0 ? "," : "") + 
                    ( children[i].isLogicalExpression() ? 
                      "(" + children[i].toJavaCode() + "? 1.0 : 0.0)"  : 
                      children[i].toJavaCode() );
        s += ")";
        return s;
    }
    
    
}
